import { WebGLCanvas } from "@nirvana/canvas";
import {
  AmbientLight,
  BallGeometry,
  Camera,
  Data,
  DataElement,
  Geometry,
  Mesh,
  PointLight,
  SceneNode,
  ShaderMaterial
} from "@nirvana/core";
import { Color, Vector3 } from "@nirvana/math";
import { Shader } from "@nirvana/shaders";

async function main() {
  let canvas = document.getElementById("engine-nirvana");
  const webCanvas = new WebGLCanvas(canvas, {
    rate: 1
  });
  const engine = webCanvas.engine;

  const scene = engine.sceneManager.createScene("root");
  const camera = new Camera("", engine);
  scene.addCamera(camera);
  camera.transform.setPosition(0, 0, 20);
  const rootEntity = new SceneNode("root-entity");
  scene.addEntity(rootEntity);

  const ambLight = new AmbientLight("alight");
  ambLight.color = new Color(0.1, 0.1, 0.1, 1);
  const pLight = new PointLight("plight");
  pLight.position = new Vector3(0, 0, 20);
  pLight.color = new Color(1.0, 0.8, 0.8, 1.0);
  scene.addLight(ambLight);
  scene.addLight(pLight);

  const vs = `
  attribute vec4 POSITION;
  attribute vec3 NORMAL;

  uniform vec4 COLOR;

  uniform mat4 u_localMat;
  uniform mat4 u_modelMat;
  uniform mat4 u_viewMat;
  uniform mat4 u_projMat;
  uniform mat4 u_MVMat;
  uniform mat4 u_MVPMat;
  uniform mat4 u_normalMat;
  uniform vec3 u_cameraPos;

  uniform vec3 u_AMBIENTLIGHT_COLOR;
  uniform vec3 u_POINTLIGHT_COLOR;
  uniform vec3 u_POINTLIGHT_POSITION;
  uniform float u_POINTLIGHT_DISTANCE;
  uniform float u_POINTLIGHT_DECAY;

  varying vec3 v_position;
  varying vec3 v_normal;
  varying vec4 v_color;

  void main() {
    gl_Position = u_projMat * u_viewMat * u_modelMat * POSITION;

    // v_position = (u_modelMat * POSITION).xyz;
    // v_normal = mat3(u_MVMat) * NORMAL;
    // v_color = COLOR;

    vec3 normal = normalize(vec3(NORMAL));// 归一化法向量  
    vec3 dir = normalize(u_POINTLIGHT_POSITION - vec3(POSITION));// 计算入射光线反方向并归一化  
    float cos = max(dot(dir, normal), 0.0);// 计算入射角余弦值  
    vec3 diffuse = u_POINTLIGHT_COLOR * vec3(COLOR) * cos;// 计算平行光漫反射颜色  
    vec3 ambient = u_AMBIENTLIGHT_COLOR * COLOR.rgb;// 计算环境光反射颜色  
    v_color = vec4(diffuse + ambient, COLOR.a);// 叠加作为最终的颜色
  }
  `;
  const fs = `
  uniform mat4 u_localMat;
  uniform mat4 u_modelMat;
  uniform mat4 u_viewMat;
  uniform mat4 u_projMat;
  uniform mat4 u_MVMat;
  uniform mat4 u_MVPMat;
  uniform mat4 u_invMat;
  uniform mat4 u_normalMat;
  uniform vec3 u_cameraPos;

  // #ifdef AmbientLight_COUNT
  //   uniform vec3 u_AMBIENTLIGHT_COLOR;
  // #endif

  // // #ifdef PointLight_COUNT
  //   uniform vec3 u_POINTLIGHT_COLOR;
  //   uniform vec3 u_POINTLIGHT_POSITION;
  //   uniform float u_POINTLIGHT_DISTANCE;
  //   uniform float u_POINTLIGHT_DECAY;
  // // #endif

  varying vec3 v_position;
  varying vec3 v_normal;
  varying vec4 v_color;

  void main() {
    gl_FragColor = v_color;

    // #ifdef AmbientLight_COUNT
    //   vec3  lightVec  = u_POINTLIGHT_POSITION - v_position;
    //   vec3  invLight  = normalize(u_invMat * vec4(lightVec, 0.0)).xyz;
    //   vec3  invEye    = normalize(u_invMat * vec4(u_cameraPos, 0.0)).xyz;
    //   vec3  halfLE    = normalize(invLight + invEye);
    //   float diffuse   = clamp(dot(v_normal, invLight), 0.0, 1.0) + 0.2;
    //   float specular  = pow(clamp(dot(v_normal, halfLE), 0.0, 1.0), 50.0);
    //   vec4  destColor = v_color * vec4(vec3(diffuse), 1.0) + vec4(vec3(specular), 1.0) + vec4(u_AMBIENTLIGHT_COLOR, 1.0);
    //   gl_FragColor = destColor;
    // #endif

    // + gl_FragColor.rgb * pl;
    
  }
`;

  const shader = Shader.create("light-demo", vs, fs);
  const material = new ShaderMaterial("", shader);
  material.shaderData.enableMacro("AmbientLight_COUNT", 2.0);
  material.shaderData.enableMacro("PointLight_COUNT", 2.0);
  material.shaderData.setColor("COLOR", new Color(0.25, 0.25, 0.75, 1.0));

  const gem = new BallGeometry(64, 64, 2.0);

  rootEntity.addChildNode(new Mesh(gem, material));

  engine.update = () => {
    rootEntity.transform.translate(0, 0, -0.01);
    rootEntity.transform.rotate(0, -0.01, 0);
  };
}

main();
